package com.yusvn.scm.admin.service;

import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.yusvn.scm.common.BaseService;
import com.yusvn.scm.common.kit.RetKit;
import com.yusvn.scm.common.model.SysRole;
import com.yusvn.scm.common.model.SysUser;

/**
 * 用户管理
 * @author liugz
 *
 */
public class AdminUserService extends BaseService {

	private SysUser dao = new SysUser().dao();
	private SysRole roleDao = new SysRole().dao();

	public Page<SysUser> page(Kv kv) {
		Page<SysUser> list = dao.template("admin.user.page", kv).paginate(getPage(kv), getLimit(kv));
		
		// 给用户添加角色
        selectUserRoles(list.getList());
        
		return list;
	}
	
    /**
     * 给用户添加角色
     */
    private void selectUserRoles(List<SysUser> users) {
        if (users != null && users.size() > 0) {
        	List<Integer> userIds = users.stream().map(SysUser::getUserId).collect(Collectors.toList());
            
            Kv kv = Kv.create().set("userIds", userIds);
            List<SysRole> userRoles = roleDao.template("admin.user.userRoles", kv).find();
            
            for (SysUser user : users) {
            	List<SysRole> roles = userRoles.stream().filter(d -> user.getUserId().equals(d.getUserId())).collect(Collectors.toList());
                user.setRoles(roles);
            }
        }
    }
    
	public boolean exists(int userId, String name) {
		name = name.toLowerCase().trim();
		String sql = "select user_id from sys_user where (nickname = ? ) and user_id != ? limit 1";
		Integer id = Db.queryInt(sql, name, userId);
		return id != null;
	}
	
	public RetKit add(String jsonStr) {
		SysUser user = JSON.parseObject(jsonStr, SysUser.class);
		
		if (exists(-1, user.getNickname() )) {
			return RetKit.fail("名称已经存在，请输入别的名称");
		}
		
		user.setUsername(user.getUsername().trim()); //
		// 密码加盐 hash
		String salt = HashKit.generateSaltForSha256();
		user.setPassword(HashKit.sha256(salt + user.getPassword().trim() ));
		user.setSalt(salt);
		
		if(user.save()) {
			addUserRoles(user.getUserId(), user.getRoleIds(), false);
			return RetKit.ok("添加成功");
		}
		
		return RetKit.fail("添加失败");
	}
	
	public RetKit resetPassword(String id) {
		// 密码加盐 hash
		String salt = HashKit.generateSaltForSha256();
		String password = HashKit.sha256(salt + "888888" );
		int cnt = Db.update("update sys_user set password=?, salt=? where user_id=? ", password, salt, id);
		if(cnt>0) {
			return RetKit.ok("重置密码为 888888");
		}
		return RetKit.fail("重置密码失败");
	}

	public RetKit update(String jsonStr) {
		SysUser user = JSON.parseObject(jsonStr, SysUser.class);
		
		if (exists(user.getUserId(), user.getNickname() )) {
			return RetKit.fail("名称已经存在，请输入别的名称");
		}
		
		user.setUsername(user.getUsername().trim());
		
		if(user.update()) {
			addUserRoles(user.getUserId(), user.getRoleIds(), true);
			return RetKit.ok("修改成功");
		}
		
		return RetKit.fail("修改失败");
	}

	public RetKit remove(String id) {
		if(dao.deleteById(id)) {
			return RetKit.ok("删除成功");
		}
		return RetKit.fail("删除失败");
	}

	public RetKit removeBatch(String idsStr) {
		JSONObject idsObj = JSON.parseObject(idsStr);
		JSONArray idsArr = idsObj.getJSONArray("ids");
		
		Object[][] paras = new Object[idsArr.size()][1];
		for(int i=0;i<idsArr.size();i++) {
			paras[i][0] = idsArr.get(i);
		}
		
		int[] cntArr = Db.batch("delete from sys_user where user_id=? ", paras, 100);
		
		int cntOk = 0;
		for(int i=0; i<cntArr.length; i++) {
			cntOk = cntOk + cntArr[i];
		}
		
		if(cntArr.length>0) {
			return RetKit.ok("成功删除 "+cntOk+" 条数据");
		}
		
		return RetKit.fail("批量删除失败");
	}
	
	
	/**
	 * 修改登录密码
	 */
	public RetKit updatePassword(Kv kv) {
		String oldPsw = kv.getStr("oldPsw");
		String newPsw = kv.getStr("newPsw");
		int userId = kv.getInt("userId");
		
		if (StrKit.isBlank(oldPsw)) {
			return RetKit.fail("原密码不能为空");
		}
		if (StrKit.isBlank(newPsw)) {
			return RetKit.fail("新密码不能为空");
		}
		if (newPsw.length() < 3) {
			return RetKit.fail("新密码长度不能小于 3");
		}

		SysUser user = dao.findById(userId);
		String salt = user.getSalt();
		String hashedPass = encodePsw(oldPsw, salt);
		if ( ! hashedPass.equals(user.getPassword())) {
			return RetKit.fail("原密码不正确，请重新输入");
		}

		salt = HashKit.generateSaltForSha256();
		newPsw = encodePsw(newPsw, salt);
		int result = Db.update("update sys_user set password=?, salt=? where user_id=? limit 1", newPsw, salt, userId);
		if (result > 0) {
			return RetKit.ok("密码更新成功");
		} else {
			return RetKit.fail("未找到账号，请联系管理员");
		}
	}

	/**
	 * 加密用户密码
	 * @param psw 密码明文
	 * @param salt 盐
	 * @return
	 */
	public String encodePsw(String psw, String salt) {
		return HashKit.sha256(salt + psw);
	}


    /**
     * 添加用户角色
     */
    private void addUserRoles(Integer userId, List<Integer> roleIds, boolean deleteOld) {
    	//先删除
        if (deleteOld) {
            Db.delete("delete from sys_user_role where user_id=? ", userId);
        }
        //再批量新增
		Object[][] paras = new Object[roleIds.size()][2];
		for(int i=0;i<roleIds.size();i++) {
			paras[i][0] = userId;
			paras[i][1] = roleIds.get(i);
		}
		
		int[] cntArr = Db.batch("insert into sys_user_role(user_id, role_id) values(?,?)", paras, 100);
		
		int cntOk = 0;
		for(int i=0; i<cntArr.length; i++) {
			cntOk = cntOk + cntArr[i];
		}
		
    }
    
	/**
	 * 更新用户状态
	 */
	public RetKit state(String jsonStr) {
		JSONObject jsonObj = JSONObject.parseObject(jsonStr);
		
//		JSONArray arr = jsonObj.getJSONArray("arr"); //前台传的数组 , {'userId':1, 'arr': [1,2,3], 'obj': {'test':123, 'test2': '对象名称'} }
//		System.out.println(" arr:"+arr);
//		JSONObject obj = jsonObj.getJSONObject("obj"); //前台传的对象
//		System.out.println(" obj:"+obj);
		
		int userId = jsonObj.getInteger("userId");
		int state = jsonObj.getInteger("state");
		
		int tf = Db.update("update sys_user set state=? where user_id=? ", state, userId);
		if(tf>0) {
			return RetKit.ok("更新状态成功");
		}
		return RetKit.fail("更新状态失败");
	}
	
}
